package de.tum.in.eist.poll.client.control;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.Widget;

import de.tum.in.eist.poll.client.gui.Dashboard;
import de.tum.in.eist.poll.client.gui.Headline;
import de.tum.in.eist.poll.client.gui.LectureVotePanel;
import de.tum.in.eist.poll.client.gui.LectureWidget;
import de.tum.in.eist.poll.shared.Feedback;
import de.tum.in.eist.poll.shared.Lecture;

public class LectureWidgetHandler {

	private LectureWidget widget;
	private AsyncCallback<Lecture> callback;
	private ClickHandler handler;
	private Headline headline;
	private Dashboard dashboard;

	public LectureWidgetHandler(LectureWidget widget,Headline headline, Dashboard dashboard) {
		this.widget = widget;
		this.headline = headline;
		this.dashboard = dashboard;
		init();
	}

	private void init() {
		handler = createClickHandler();
		initCallback();
		widget.addHideButtonClickHandler(handler);
		widget.addMinimizeButtonClickHandler(handler);
		widget.getTopic().addClickHandler(handler);
		widget.getSubmitButton().addClickHandler(createSubmitButtonHandler());
	}

	/**
	 * Create a {@link ClickHandler} to minimize or maximize the lecture view
	 * and to hide the notification that this lecture view has been updated.
	 * 
	 * @return the new {@link ClickHandler}
	 */
	public ClickHandler createClickHandler() {
		return new ClickHandler() {
			/**
			 * Minimize the lecture widget to the headline or maximize it
			 */
			@Override
			public void onClick(ClickEvent event) {
				// Hide button
				if (event.getSource().equals(widget.getHideButton())) {
					widget.hideNotification();
					widget.getUser().clearNotification(widget.getLecture());
					headline.updateNotificationNumber();
				} 
				// Minimize button
				else if (event.getSource().equals(widget.getMinimizeButton())
						|| event.getSource().equals(widget.getTopic())) {
					if (widget.isMinimized()) {
//						((Widget)event.getSource()).removeStyleName("expand");
						((Widget)event.getSource()).addStyleName("collapse");
						widget.expand();
					} else {
//						((Widget)event.getSource()).addStyleName("expand");
						((Widget)event.getSource()).removeStyleName("collapse");
						widget.collapse();
					}
				}
			}
		};
	}

	/**
	 * initialize the {@link AsyncCallback} to react on faulty or successful
	 * feedback transfer
	 */
	public void initCallback() {
		callback = new AsyncCallback<Lecture>() {

			@Override
			public void onFailure(Throwable caught) {
				widget.getErrorLabel().setText(caught.getMessage());
			}

			/**
			 * update the chart with the new Feedback and remove the vote panel
			 * and submit button
			 * 
			 * @param result
			 *            the updated lecture
			 */
			@Override
			public void onSuccess(Lecture result) {
				widget.update(result);
				widget.updateChart(result.getStats());

				// Update over all chart
				if (dashboard.isOverAllChartVisible()) {
					dashboard.updateOverAllChart();
				}
			}
		};
	}

	/**
	 * @return a ClickHandler to submit the user input to the server
	 */
	public ClickHandler createSubmitButtonHandler() {
		return new ClickHandler() {
			/**
			 * Send the user input to the server.
			 */
			@Override
			public void onClick(ClickEvent event) {
				// Clear text area at first click
				if (widget.getVotePanel().getPositiveTextArea().getText()
						.equals(LectureVotePanel.POSITIVE_QUESTION)) {
					widget.getVotePanel().getPositiveTextArea().setText("");
				}
				if (widget.getVotePanel().getNegativeTextArea().getText()
						.equals(LectureVotePanel.NEGATIVE_QUESTION)) {
					widget.getVotePanel().getNegativeTextArea().setText("");
				}
				
				// input check
				// input must be between 1 and 10 chars that are numbers, letters, or dots.
				if(!inputIsValid(widget.getVotePanel().getPositiveTextArea()) || !inputIsValid(widget.getVotePanel().getNegativeTextArea())){
					Window.alert("Text must not contain special characters and has to be shorter than 255 characters.");
					return;
				}
				
				EIST_POLL.pollSvc.postFeedback(widget.getUser(), widget
						.getLecture(), new Feedback(widget.getUser(), widget
						.getVotePanel().getVote(), widget.getVotePanel()
						.getPositiveAnswer(), widget.getVotePanel()
						.getNegativeAnswer()), callback);
				widget.removeVotePanel();
			}
		};
	}

	public boolean inputIsValid(TextArea textArea) {
		String input = textArea.getText();
		if (input.contains("<") || input.contains(">") || input.contains(";")
				|| input.contains("{") || input.contains("}")
				|| input.contains("/") || input.length() >= 255) {
			textArea.selectAll();
			return false;
		}
		return true;
	}
}
